using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.Windows;
using System.Reflection;
using System.IO;

namespace miciv.Rendering
{
    public class TextureManager
    {
        public class ManagedTexture : IManagedResource
        {
            static protected Texture s_textureLoadFailed = null;
            static protected ImageInformation s_imageInformationTextureLoadFailed;
            protected Device m_device;
            protected string m_strTextureID;
            protected Texture m_texture;
            protected ImageInformation m_imageInformation;

            public Texture Texture
            {
                get
                {
                    return this.m_texture;
                }
            }

            public ImageInformation Info
            {
                get
                {
                    return this.m_imageInformation;
                }
            }

            public ManagedTexture(Device _device, string _strTextureID)
            {
                this.m_device = _device;
                this.m_strTextureID = _strTextureID;
                this.m_imageInformation = new ImageInformation();
                this.Load();
            }

            public void DeviceLost()
            {
                this.m_texture.Dispose();
                this.m_texture = null;
            }

            public void DeviceReset()
            {
                this.Load();
            }

            protected void Load()
            {
                try
                {
                    this.m_texture = Texture.FromFile(this.m_device, this.m_strTextureID,
                        0, 0, 0, Usage.None, Format.Unknown, Pool.Default, Filter.Linear, Filter.Linear, 0,
                        out this.m_imageInformation);
                }
                catch (SlimDXException e)
                {
                    System.Diagnostics.Debug.WriteLine(e.Message);
                    if (null == ManagedTexture.s_textureLoadFailed)
                    {
                        Assembly assembly = Assembly.GetExecutingAssembly();
                        Stream stream = assembly.GetManifestResourceStream("miciv.Resources.TextureLoadFailed.png");
                        ManagedTexture.s_imageInformationTextureLoadFailed = new ImageInformation();
                        ManagedTexture.s_textureLoadFailed = Texture.FromStream(this.m_device, stream, (int)stream.Length,
                            0, 0, 0, Usage.None, Format.R8G8B8, Pool.Default, Filter.Linear, Filter.Linear, 0,
                            out ManagedTexture.s_imageInformationTextureLoadFailed);
                    }
                    this.m_texture = ManagedTexture.s_textureLoadFailed;
                    this.m_imageInformation = ManagedTexture.s_imageInformationTextureLoadFailed;
                }
            }
        }

        protected Device m_device;
        protected CoreContext m_coreContext;
        protected Hashtable m_htblManagedTextures;
        protected ManagedResourceManager m_managedResourceManager;

        public TextureManager()
        {
            this.m_htblManagedTextures = new Hashtable();
        }

        public bool Initialize(CoreContext _coreContext)
        {
            this.m_coreContext = _coreContext;
            this.m_device = this.m_coreContext.GetData<Device>("D3DDevice");
            this.m_managedResourceManager = this.m_coreContext.GetData<ManagedResourceManager>("ManagedResourceManager");
            return true;
        }

        public ManagedTexture GetTexture(string _strTextureID)
        {
            if (false != this.m_htblManagedTextures.ContainsKey(_strTextureID))
            {
                return this.m_htblManagedTextures[_strTextureID] as ManagedTexture;
            }
            ManagedTexture tex = new ManagedTexture(this.m_device, _strTextureID);
            this.m_managedResourceManager.Add(tex);
            this.m_htblManagedTextures.Add(_strTextureID, tex);
            return tex;
        }

        public void Release()
        {
            this.m_htblManagedTextures.Clear();
        }
    }
}
